package com.anxin.registerManagement.log;

import com.anxin.registerManagement.bean.persist.LogInfo;
import com.anxin.registerManagement.mapper.LogInfoMapper;
import com.anxin.registerManagement.util.Const;
import com.anxin.registerManagement.util.jwt.JwtUtil;
import eu.bitwalker.useragentutils.UserAgent;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

@Aspect
@Component
public class LogAspect {

    @Autowired
    LogInfoMapper logInfoMapper;

    private final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    //表示匹配带有自定义注解的方法
    @Pointcut("@annotation(com.anxin.registerManagement.log.Log)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) {
        Object result = null;
        long beginTime = System.currentTimeMillis();

        try {
            logger.info("我在目标方法之前执行！");
            result = point.proceed();
            long endTime = System.currentTimeMillis();
            insertLog(point, endTime - beginTime);
        } catch (Throwable e) {
            logger.error(e.getMessage());
        }
        return result;
    }

    private void insertLog(ProceedingJoinPoint point, long time) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        LogInfo logInfo = new LogInfo();
        //操作者编号
        // TODO:这里通过jwt去解析id
//        String jwtToken = request.getHeader(Const.jwtName);
//        String userId = JwtUtil.getClaim(jwtToken, "id");
        String userId = "1";
        logInfo.setHandleUserId(Integer.parseInt(userId));
        //操作名称
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        Log action = method.getAnnotation(Log.class);
        logInfo.setHandleName(action.value());
        //请求路径
        String url = request.getRequestURI();
        logInfo.setRequestUrl(url);
        //操作系统类型，客户端类型
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("user-agent"));
        String osType = userAgent.getOperatingSystem().getName();
        String clientType = userAgent.getOperatingSystem().getDeviceType().toString();
        logInfo.setOsType(osType);
        logInfo.setClientType(clientType);
        //插入
        logInfoMapper.insert(logInfo);
    }
}
